using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Cysharp.Threading.Tasks;
using IQIGame.Onigao.Game;
using UnityEditor;
using UnityEngine;

namespace IQIGame.Onigao.GamePlay.Editors
{
    public class CharacterEffectReuse
    {
        [MenuItem("GameEditor/Effect/战斗特效资源分析", false, 2)]
        public static void BatchEffect()
        {
            new CharacterEffectReuse().ResetConfig().Forget();
        }

        private async UniTaskVoid ResetConfig()
        {
            // 读CSV
            var rCsvPath = Path.Combine(Path.GetDirectoryName(Application.dataPath), "Tables/Editor/EffectReuse.csv");

            var rCsvStr = File.ReadAllText(rCsvPath); //AssetDatabase.LoadAssetAtPath<TextAsset>(rCsvPath).text;
            Dictionary<int, int> rHeroReuse = new Dictionary<int, int>();
            Dictionary<int, int> rMonsterReuse = new Dictionary<int, int>();
            var rLines = rCsvStr.Split('\n');
            // 第一行是表头
            for (int i = 1; i < rLines.Length; i++)
            {
                var rLine = rLines[i];
                var rStrs = rLine.Split(',');
                if (rStrs.Length > 1 && int.TryParse(rStrs[0], out var nHeroID) && int.TryParse(rStrs[1], out var nHeroReuse))
                {
                    rHeroReuse.TryAdd(nHeroID, nHeroReuse);
                }
                if (rStrs.Length > 3 && int.TryParse(rStrs[2], out var nMonsterID) && int.TryParse(rStrs[3], out var nMonsterReuse))
                {
                    rMonsterReuse.TryAdd(nMonsterID, nMonsterReuse);
                }
            }

            if (TableCenter.heroSkin == null)
            {
                await TableCenter.LoadTables();
            }

            var rReusePath = Path.Combine("Assets/" + PathConstant.ScriptableObjectPath + "/Battle/EffectReuse", "EffectReuse.asset");
            var rReuseConfig = AssetDatabase.LoadAssetAtPath<EffectReuseConfig>(rReusePath);
            if (rReuseConfig == null)
            {
                rReuseConfig = ScriptableObject.CreateInstance<EffectReuseConfig>();
                AssetDatabase.CreateAsset(rReuseConfig, rReusePath);
            }
            rReuseConfig.resuse.Clear();
            foreach (var rPair in rHeroReuse)
            {
                var rCurRes = TableCenter.heroSkin.Get(rPair.Key);
                var rTargetRes = TableCenter.heroSkin.Get(rPair.Value);
                var rCurEffectFiles = Directory.GetFiles("Assets/" + PathConstant.CharacterPath + rCurRes.BattleEntityAsset + "/Effect");
                var rTargetEffectFiles = Directory.GetFiles("Assets/" + PathConstant.CharacterPath + rTargetRes.BattleEntityAsset + "/Effect");

                for (int i = 0; i < rTargetEffectFiles.Length; i++)
                {
                    var rName = Path.GetFileNameWithoutExtension(rTargetEffectFiles[i]);
                    if (rName.Contains(".meta"))
                    {
                        continue;
                    }
                    var rDict = rReuseConfig.resuse;
                    if (rCurEffectFiles.All(x => Path.GetFileNameWithoutExtension(x) != rName))
                    {
                        if (!rDict.TryGetValue(rCurRes.BattleEntityAsset, out var rValue))
                        {
                            rValue = new Dictionary<string, string>();
                            rDict.Add(rCurRes.BattleEntityAsset, rValue);
                        }
                        rValue[rName] = rTargetRes.BattleEntityAsset;
                    }
                }
            }
            foreach (var rPair in rMonsterReuse)
            {
                var rCurRes = TableCenter.monster.Get(rPair.Key);
                var rTargetRes = TableCenter.monster.Get(rPair.Value);
                if (rCurRes == null || rTargetRes == null)
                {
                    continue;
                }
                var rCurEffectPath = "Assets/" + PathConstant.EntityPath + rCurRes.EntityAsset + "/Effect";
                var rCurEffectFiles = Array.Empty<string>();
                if (Directory.Exists(rCurEffectPath))
                {
                    rCurEffectFiles = Directory.GetFiles(rCurEffectPath);
                }
                var rTargetEffectPath = "Assets/" + PathConstant.EntityPath + rTargetRes.EntityAsset + "/Effect";
                var rTargetEffectFiles = Array.Empty<string>();
                if (Directory.Exists(rTargetEffectPath))
                {
                    rTargetEffectFiles = Directory.GetFiles(rTargetEffectPath);
                }
                for (int i = 0; i < rTargetEffectFiles.Length; i++)
                {
                    var rName = Path.GetFileName(rTargetEffectFiles[i]);
                    if (rName.Contains(".meta"))
                    {
                        continue;
                    }
                    var rDict = rReuseConfig.resuse;
                    if (rCurEffectFiles.All(x => Path.GetFileName(x) != rName))
                    {
                        if (!rDict.TryGetValue(rCurRes.EntityAsset, out var rValue))
                        {
                            rValue = new Dictionary<string, string>();
                            rDict.Add(rCurRes.EntityAsset, rValue);
                        }
                        var rEffectName = rName.Replace(".prefab", "");
                        rValue[rEffectName] = rTargetRes.EntityAsset;
                    }
                }
            }
            EditorUtility.SetDirty(rReuseConfig);
            
            var rPreloadPath = Path.Combine("Assets/" + PathConstant.ScriptableObjectPath + "/Battle/EffectReuse", "EffectPreload.asset");
            var rPreloadConfig = AssetDatabase.LoadAssetAtPath<EffectPreloadConfig>(rPreloadPath);
            if (rPreloadConfig == null)
            {
                rPreloadConfig = ScriptableObject.CreateInstance<EffectPreloadConfig>();
                AssetDatabase.CreateAsset(rPreloadConfig, rPreloadPath);
            }
            // 记录全部特效用来预载
            rPreloadConfig.effects.Clear();
            var rHeroSkins = TableCenter.heroSkin.DataList;
            for (int i = 0; i < rHeroSkins.Count; i++)
            {
                var rSkin = rHeroSkins[i];
                var rRes = rSkin.BattleEntityAsset;
                if (rPreloadConfig.effects.ContainsKey(rRes))
                {
                    continue;
                }
                // 如果有复用，除了自己的还要加上复用列表中的特效
                var rEffectList = new List<string>();
                if (rReuseConfig.resuse.TryGetValue(rRes, out var rDict))
                {
                    rEffectList.AddRange(rDict.Keys.ToList());
                }
                var rDirectory = "Assets/" + PathConstant.CharacterPath + rRes + "/Effect";
                if (!Directory.Exists(rDirectory))
                {
                    continue;
                }
                var rFiles = Directory.GetFiles(rDirectory);
                for (int j = 0; j < rFiles.Length; j++)
                {
                    if (rFiles[j].EndsWith(".prefab"))
                    {
                        rEffectList.Add(Path.GetFileNameWithoutExtension(rFiles[j]));
                    }
                }
                rPreloadConfig.effects.Add(rRes, rEffectList);
            }
            var rMonsters = TableCenter.monster.DataList;
            for (int i = 0; i < rMonsters.Count; i++)
            {
                var rMonster = rMonsters[i];
                var rRes = rMonster.EntityAsset;
                if (rPreloadConfig.effects.ContainsKey(rRes))
                {
                    continue;
                }
                // 如果有复用，复用内有全量特效列表
                if (rReuseConfig.resuse.TryGetValue(rRes, out var rDict))
                {
                    rPreloadConfig.effects.Add(rRes, rDict.Keys.ToList());
                }
                else
                {
                    var rEffectList = new List<string>();
                    var rDirectory = "Assets/" + PathConstant.EntityPath + rRes + "/Effect";
                    if (!Directory.Exists(rDirectory))
                    {
                        continue;
                    }
                    var rFiles = Directory.GetFiles(rDirectory);
                    for (int j = 0; j < rFiles.Length; j++)
                    {
                        if (rFiles[j].EndsWith(".prefab"))
                        {
                            rEffectList.Add(Path.GetFileNameWithoutExtension(rFiles[j]));
                        }
                    }
                    rPreloadConfig.effects.Add(rRes, rEffectList);
                }
            }
            EditorUtility.SetDirty(rPreloadConfig);
            
            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();

            Debug.Log("分析完成");
        }
    }
}